package cn.qu.dockman.mgr.ws;

import cn.qu.dockman.mgr.ws.exec.CommandParser;
import cn.qu.dockman.protocol.command.Command;
import cn.qu.dockman.protocol.def.CommandFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

/**
 * Created by zh on 17/3/14.
 */
public class WebSocketServer extends AbstractWebSocketHandler implements ApplicationContextAware, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);

    private static Class<? extends CommandParser> findClass(String className) {
        try {
            return (Class<? extends CommandParser>) Class.forName("cn.qu.dockman.mgr.ws.exec." + className);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Command command = CommandFactory.getCommand(message.getPayload());

        logger.debug("接收到消息:{}->{}", session.getId(), message.toString());
        String serviceName = command.getClass().getSimpleName() + "Parser";
        Class<? extends CommandParser> clazz = findClass(serviceName);
        if (clazz == null) {
            logger.error("未支持的Command: {}", command.getHeader().getName());
        } else {
            CommandParser parser = clazz.newInstance();
            parser.setApplicationContext(this.applicationContext);
            parser.setHost(session.getRemoteAddress().getAddress().getHostAddress());
            parser.setPort(session.getRemoteAddress().getPort());
            parser.setHostname(session.getRemoteAddress().getHostName());
            parser.before();
            parser.parse(command);

            logger.debug("消息已处理完成:{}", session.getId());
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sendingQueue.removeSession(session);
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sendingQueue.newSession(session);
    }

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    private SendingQueue sendingQueue;

    @Override
    public void afterPropertiesSet() throws Exception {
        this.sendingQueue = applicationContext.getBean(SendingQueue.class);
    }
}
